﻿@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;
@using Microsoft.AspNetCore.Http;
@using Microsoft.Extensions.Options;
@using SimpleIdServer.IdServer.Helpers
@using SimpleIdServer.IdServer.Website.Infrastructures
@using SimpleIdServer.IdServer.Website.Resources;
@using SimpleIdServer.IdServer.Website.Shared.Dialogs
@using SimpleIdServer.IdServer.Website.Stores.AcrsStore;
@using SimpleIdServer.IdServer.Website.Stores.RealmStore;
@using SimpleIdServer.IdServer.Website.Stores.RegistrationWorkflowStore;
@using System.Security.Claims
@inject IUrlHelper urlHelper
@inject DialogService dialogService
@inject NavigationManager navigationManager
@inject ContextMenuService contextMenuService
@inject NotificationService notificationService
@inject IOptions<IdServerWebsiteOptions> Options;
@inject IState<RealmsState> realmsState
@inject IDispatcher dispatcher
@inject IState<AcrsState> acrsState
@inject IState<RegistrationWorkflowsState> registrationWorkflowsState
@inherits Fluxor.Blazor.Web.Components.FluxorComponent

<div>    
    <div class="row">
        <div class="col">
            <RadzenText class="mt-3 mb-3 no-margin" Text="@Global.AcrWorkflowsTitle" TextStyle="TextStyle.DisplayH3" />
            <p>
                @Global.AcrsDescription
            </p>
        </div>
        <div class="col-3">
            <SidAuthorizeView Roles=@("/acrs/manage")>
                <Authorized>
                    <RadzenButton class="mb-1" Click="@(args => AddAcr())" Icon="add" Text="@Global.AddAcr" ButtonStyle="ButtonStyle.Primary" Size="ButtonSize.Medium"></RadzenButton>
                </Authorized>
            </SidAuthorizeView>
        </div>
    </div>

    <RadzenDataGrid @ref="acrsGrid"
    AllowFiltering="true"
    AllowColumnResize="true"
    AllowAlternatingRows="false"
    AllowSorting="true"
    PageSize="30"
    AllowPaging="true"
    PagerHorizontalAlign="HorizontalAlign.Left"
    ShowPagingSummary="true"
    IsLoading="@acrsState.Value.IsLoading"
    Count="@acrsState.Value.Count"
    Data="@acrsState.Value.Acrs"
    LoadData="@LoadData"
    RowRender="@RowRender"
    TItem="SelectableAcr"
    ColumnWidth="300px">
        <Columns>
            <RadzenDataGridColumn TItem="SelectableAcr" Filterable="false" Sortable="false" Width="80px" TextAlign="TextAlign.Center">
                <HeaderTemplate>
                    <RadzenCheckBox @bind-Value=@selectAll Change="@(args => ToggleAll(args))" TValue="bool" />
                </HeaderTemplate>
                <Template Context="data">
                    <RadzenCheckBox @bind-Value=@data.IsSelected Change="@(args => ToggleChanged(args, data))" TValue="bool" />
                </Template>
            </RadzenDataGridColumn>
            <RadzenDataGridColumn TItem="SelectableAcr" Filterable="true" Property="Value.Name" Sortable="false" Title="@Global.Name" Width="80px">
                <Template Context="data">
                    @if(string.IsNullOrWhiteSpace(data.Value.AuthenticationWorkflow))
                    {
                        @data.Value.Name
                    }
                    else
                    {
                        <RadzenLink Path="@urlHelper.GetUrl($"/acrs/workflows/{data.Value.Id}")">@data.Value.Name</RadzenLink>
                    }
                </Template>
            </RadzenDataGridColumn>
            <RadzenDataGridColumn TItem="SelectableAcr" Property="Value.DisplayName" Filterable="true" Sortable="false" Title="@Global.DisplayName" Width="80px" />
            <RadzenDataGridColumn TItem="SelectableAcr" Property="Value.UpdateDateTime" Filterable="true" Sortable="true" FormatString="{0:dd/M/yyyy HH:mm:ss}" SortOrder="SortOrder.Descending" Title="@Global.UpdateDateTime" Width="80px" />
            <RadzenDataGridColumn TItem="SelectableAcr" Filterable="false" Sortable="false" FormatString="{0:dd/M/yyyy HH:mm:ss}" Width="80px" TextAlign="TextAlign.Center">
                <Template Context="data">
                    <RadzenButton Icon="more_vert" Click="@(args => ShowMoreContextMenu(data, args))" />
                </Template>
            </RadzenDataGridColumn>
        </Columns>
    </RadzenDataGrid>
</div>

@code {
    RadzenDataGrid<SelectableAcr> acrsGrid;
    [Inject] private IRealmStore realmStore { get; set; }
    [Inject] private IOptions<IdServerWebsiteOptions> options { get; set; }
    [CascadingParameter] private Task<AuthenticationState> authenticationStateTask { get; set; }
    bool selectAll = false;
    string activeRealm;

    protected override void OnAfterRender(bool firstRender)
    {
        base.OnAfterRender(firstRender);
        if (firstRender)
        {
            SubscribeToAction<DeleteSelectedAcrsSuccessAction>((act) =>
            {
                notificationService.Notify(new NotificationMessage { Severity = NotificationSeverity.Success, Summary = Global.SelectedAcrsRemoved });
                StateHasChanged();
            });
            SubscribeToAction<CreateAcrWorkflowSuccessAction>((act) =>
            {
                notificationService.Notify(new NotificationMessage { Severity = NotificationSeverity.Success, Summary = Global.WorkflowIsCreated });
                StateHasChanged();
            });
            if (!acrsState.Value.IsLoading && acrsGrid != null)
                acrsGrid?.Reload();
        }
    }

    protected override async Task OnInitializedAsync()
    {
        base.OnInitializedAsync();
        activeRealm = await GetRealm();
    }

    void ToggleChanged(bool isSelected, SelectableAcr acr)
    {
        var act = new ToggleAcrSelectionAction { IsSelected = isSelected, Name = acr.Value.Name };
        dispatcher.Dispatch(act);
    }

    void ToggleAll(bool isSelected)
    {
        var act = new ToggleAllAcrSelectionAction { IsSelected = isSelected };
        dispatcher.Dispatch(act);
    }

    void ShowMoreContextMenu(SelectableAcr acr, MouseEventArgs args)
    {
        var authState = authenticationStateTask.Result;
        var user = authState.User;
        var realm = !options.Value.IsReamEnabled ? SimpleIdServer.IdServer.Constants.DefaultRealm : realmStore.Realm;
        var canManage = user.Claims.Any(c => c.Type == ClaimTypes.Role && c.Value.Contains($"{realm}/acrs/manage"));
        var acrIds = acrsState.Value.Acrs?.Where(c => c.IsSelected).Select(c => c.Value.Id)?.ToList() ?? new List<string>();
        if (!acrIds.Contains(acr.Value.Id))
        {
            acrIds.Add(acr.Value.Id);
        }

        var menuItems = new List<ContextMenuItem>();
        if (canManage)
        {
            menuItems.Add(new ContextMenuItem { Text = Global.Delete, Value = 1 });
            if(acrIds.Count() == 1)
            {
                var selectedAcr = acrsState.Value.Acrs.Single(c => c.Value.Id == acrIds.First());
                if (string.IsNullOrWhiteSpace(selectedAcr.Value.AuthenticationWorkflow))
                {
                    menuItems.Add(new ContextMenuItem { Text = Global.CreateWorkflow, Value = 2 });
                }
            }
        }

        menuItems.Add(new ContextMenuItem { Text = Global.Demo, Value = 3 });
        contextMenuService.Open(args, menuItems, (a) =>
        {
            if (a.Value.Equals(1))
            {
                var act = new DeleteSelectedAcrsAction { Ids = acrIds };
                dispatcher.Dispatch(act);
                contextMenuService.Close();
            }
            else if(a.Value.Equals(2))
            {
                var act = new CreateAcrWorkflowAction { Id = acrIds.First() };
                dispatcher.Dispatch(act);
                contextMenuService.Close();
            }
            else if(a.Value.Equals(3)) 
            {
                var url = GetDemoUrl(acr);
                navigationManager.NavigateTo(url, true);
            }
        });
    }

    void LoadData(LoadDataArgs args)
    {
        var act = new GetAllAcrsAction();
        dispatcher.Dispatch(act);
    }

    void RowRender(RowRenderEventArgs<SelectableAcr> row)
    {
        const string className = "class";
        if (row.Data.IsNew)
            row.Attributes.Add(className, "new");
        else if (row.Data.IsSelected)
            row.Attributes.Add(className, "active");
        else if (row.Attributes.ContainsKey(className))
            row.Attributes.Remove(className);
    }

    async void AddAcr()
    {
        await dialogService.OpenAsync<AddAcrDialog>(Global.AddAcr, new Dictionary<string, object>(), new DialogOptions
        {
            Width = "700px",
            Height = "512px",
            Resizable = true,
            Draggable = true
        });
    }

    string GetDemoUrl(SelectableAcr selectableAcr)
    {
        var realm = string.Empty;
        if (!string.IsNullOrWhiteSpace(realmStore.Realm)) realm = $"&realm={realmStore.Realm}";
        return $"/login?acrValues={selectableAcr.Value.Name}{realm}";
    }

    async Task<string> GetRealm()
    {
        var realmStr = !string.IsNullOrWhiteSpace(realmStore.Realm) ? realmStore.Realm : SimpleIdServer.IdServer.Constants.DefaultRealm;
        return realmStr;
    }
}